<?php
namespace zake\foundation\able\traits;

use zake\foundation\able\BeeAble;
use zake\foundation\able\reactor\ConnectAble;
use zake\foundation\able\stream\ReadAble;
use zake\foundation\able\stream\WriteAble;
use zake\foundation\reactor\Reactor;
use zake\helper\Grant;

/**
 * Trait ResourceTrait
 * @package zake\foundation\able\traits
 *
 * @author liu.bin 2020-04-28 15:11
 */
trait ResourceTrait
{
    /**
     * @var int
     */
    protected $fd = 0;

    /**
     * @var null | resource
     */
    protected $resource = null;


    /**
     * 获取fd
     * @return int
     *
     * @author liu.bin 2020-04-01 00:05
     */
    public function getFd()
    {
        return $this->fd;
    }

    /**
     * 获取资源
     * @return resource
     *
     * @author liu.bin 2020-03-31 23:51
     */
    public function getResource()
    {
        return $this->resource;
    }


    /**
     * 关闭链接
     *
     * @return bool
     * @author liu.bin 2020-03-31 17:03
     */
    public function close($callBack=null)
    {
        if($this instanceof ConnectAble){
            Grant::recoveryConnectId($this->getConnectId());
        }
        // 移除读监听
        if($this instanceof ReadAble){
            Reactor::removeReadListener($this);
            $this->closeReadResource();
        }
        // 移除写监听
        if($this instanceof WriteAble){
            Reactor::removeWriteListener($this);
            $this->closeWriteResource();
        }
        // close 回调
        if($callBack instanceof \Closure){
            $callBack();
        }
        return true;
    }


    /**
     * 关闭资源
     * 一般在没有监听状态下关闭
     * 如果stream已处理监听状态，需要使用close()
     *
     * @return bool
     * @author liu.bin 2020-04-26 16:17
     */
    public function closeResource()
    {
        if(!$this->isCloseResource()){
            fclose($this->getResource());
        }
        return true;
    }


    /**
     * 判断资源是否关闭
     *
     * @return bool
     *  true    : 关闭
     *  false   : 正常链接
     *
     * @author liu.bin 2020-04-25 18:50
     */
    public function isCloseResource()
    {
        return is_resource($this->resource) ? feof($this->resource) : true;
    }

}